#include <stdio.h>
#include <stdlib.h>

int main(int argc, char const *argv[])
{
    // 32位：寻址范围 2^32  4GB      0x00000000 ~ 0xFFFFFFFF
    // 64位：寻址范围 2^64  4GB*4GB  0x0000000000000000 ~ 0xFFFFFFFFFFFFFFFF

    // int a = 100; // 4
    // printf("整型变量 a 的地址是: %p\n", &a);

    // char c = 'x'; // 1
    // printf("字符变量 c 的地址是: %p\n", &c);

    // double f = 3.14; // 8
    // printf("浮点变量 f 的地址是: %p\n", &f);

    // printf("%ld\n", sizeof(char *));
    // printf("%ld\n", sizeof(int *));
    // printf("%ld\n", sizeof(double *));


    // // 1. 指针定义、初始化，此处*是指针标记，让系统规定p专用于存储地址
    // int a = 100;
    // int *p = &a; // p是专门用来存储 int 型数据的地址的

    // // 2. 指针的赋值
    // p = &a;  // 完美匹配

    // // 3. 指针目标的引用
    //  a = 200;
    // *p = 200; // 此处的*，称为取目标符，解引用符

    // // 4. 各种指针的定义
    // int    a;
    // int  (*p);
    // p = &a; // p-->a
    // *p = 100;
    // a  = 100;

    // char   ch;
    // char  (*q);
    // q = &ch; // q-->ch
    // ch = 'a';
    // *q = 'a';

    // int *p;
    // int * (*k);
    // k = &p; // k-->p-->a
    //     a  = 100;
    // *   p  = 100;
    // * (*k) = 100;

    // int **   k ;
    // int ** (*w);
    // w = &k; // w-->k-->p-->a
    //     a  = 100;
    // *   p  = 100;
    // * (*k) = 100;
    // * (**w)= 100;

    // int     b   [3];
    // int   (*m)  [3]; // 数组指针，指向数组的指针
    // m = &b; // m-->b
    // for(int i=0; i<3; i++)
    // {
    //       b [i] = i+1;
    //     (*m)[i] = i+1;
    // }

    // void    f  (int a, float f);
    // void  (*n) (int a, float f);  // 函数指针，指向函数的指针
    // n = &f; // n-->f
    // n =  f; // 对于函数而言，取址符可以省略
    //   f (100, 3.14);    
    // (*n)(100, 3.14);    
    // ( n)(100, 3.14);    // 对于函数指针而言，取目标符可以省略
    //   n(100, 3.14);    

    // int a;
    // int *p; // p --> ???
    // p = &a;
    // *p = 100; // 将100塞到不知道哪里，触发不可预料的结果

    // int *k;
    // k = malloc(100); // k --> |        100字节       |


    // *k = 1;
    // *(k+1) = 2;
    // *(k+101) = 2; // rust
    // free(k); // k野指针

    // k = malloc(50);
    // ....
    // ....
    // ....
    // free(k);

    int *p = NULL;       // p --> 0 |////////////|
    int *p = (void *)0;  // p --> 0 |////////////|
    *p = 100;

    double *q;
    p = q; // 不兼容的指针，错误的


    void *k; // 未定目标的指针，可以匹配任意的指针
    *k = 10; // 错误的，未定类型指针不可以取目标


    double *p = malloc(100); // 申请100字节的内存
    *p = 2;
    *(p-1) = 3;

    p-n; // 让p向上增加n个目标，目标就是p的目标



    return 0;
}
